package com.wpp;

import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/*
 * 调用运行时类指定的结构:属性、方法、构造器
 *
 *
 *
 *
 * */
public class ReflectionTest1 {

    @Test
    public void test() throws Exception {
        Class cls = Person.class;

        //创建运行时类的对象
        Person p1 = (Person) cls.newInstance();

        //开发中常用
        //获取指定变量名的属性:私有的也能够正常拿到，但是私有的获取不了值或者设置值
        //必须添加一个：setAccessible(true) 才能正常设置值和获取值
        Field name = cls.getDeclaredField("name");
        System.out.println(name);

        //保证当前属性是可访问的
        name.setAccessible(true);
        //设置当前属性的值，set(给哪个对象设置属性，设置属性具体值)
        name.set(p1, "java");
        //获取哪个对象的当前属性的值
        Object o = name.get(p1);
        System.out.println(o);


    }


    @Test
    public void test1() throws Exception {

        //调用指定的方法
        Class cls = Person.class;

        //创建运行时类的对象
        Person p1 = (Person) cls.newInstance();

        //获取指定的某个方法:getDeclaredMethod(获取指明方法的名称，指明获取的方法的形参列表)
        Method show = cls.getDeclaredMethod("show", String.class);

        //获取指定变量名的属性:私有的也能够正常拿到，但是私有的获取不了值或者设置值
        //必须添加一个：setAccessible(true) 才能正常设置值和获取值
        //保证当前方法是可访问的
        show.setAccessible(true);

        //方法调用invoke(方法的调用者，方法的实参)
        show.invoke(p1, "test");

        System.out.println("*********************************************");

        Method showtime = cls.getDeclaredMethod("showtime");
        showtime.setAccessible(true);

        //invoke的返回值，就是当前方法的返回值
        Object invoke = showtime.invoke(p1);
        System.out.println(invoke);


        System.out.println("****************如何调用静态方法********************");

        Method showStatic = cls.getDeclaredMethod("showStatic");
        showStatic.setAccessible(true);

        //如果调用的运行时类的方法没有返回值，则此invoke()返回null
        //关于调用静态方法时，invoke可以不用指明哪个对象调用的，但是非静态的，必须要指明
        Object invoke1 = showStatic.invoke(p1);

    }


    /*
     * 调用运行时类的构造器
     *
     *
     *
     *
     *
     *
     * */


}
